﻿#include "mainface.h"
#include "ui_mainface.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QFileDialog>
#include <QFileInfo>
#include "userinfo.h"
#include "fileitem.h"
#include "transferinfo.h"
#include "mythread.h"

MainFace::MainFace(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainFace)
{
    ui->setupUi(this);

    setWindowIcon(QIcon(":/img/icon.png"));
    setWindowTitle("个人云存储系统");
    ui->label_icon->setScaledContents(true);
    ui->label_icon->setPixmap(QPixmap(":/img/icon.png"));

//    ui->widget_3->setStyleSheet("background-color: rgba(255, 255, 255, 0.7);");
//    ui->listWidget->setStyleSheet("background-color: rgba(255, 255, 255, 0.7);");
}

MainFace::~MainFace()
{
    delete ui;
}

// 发送到服务器
void MainFace::WriteToServer(const QJsonObject &obj)
{
    auto data = QJsonDocument(obj).toJson(); // 将QJsonObject包装成一个QJsonDocument对象,并将QJsonDocument转换为JSON格式的QByteArray
    size_t size =  data.size(); // 获取数据(data)的长度
    socket->write((char*)&size,sizeof(size_t)); // 将数据长度写入套接字(告诉接收方数据多长)
    socket->write(data); // 将Json数据写入套接字
    socket->flush();
}

// 处理json逻辑
void MainFace::process(const QByteArray &data)
{
    auto obj = QJsonDocument::fromJson(data).object();
    if (obj["flag"] == 10) // 上传信息
    {
        QString res = obj["contant"].toString();
        qDebug() << "上传信息:::" << res << endl;

        QTextStream stream(&res);
        QString line;

        while (stream.readLineInto(&line))
        {
            QStringList parts = line.split('\\');
            if (parts.size() == 3)
            {
                QString filename = parts[0];
                bool ok;
                int chunksize = parts[1].toInt(&ok);
                if (ok)
                {
                    QMutexLocker locker(&uploadProgressMutex);
                    UpLoadInfo.append({filename, chunksize});
                    uploadProgress[filename] = chunksize + 1;
                }
            }
        }
    }
    else if (obj["flag"] == 11) // 下载信息
    {
        QString res = obj["contant"].toString();
        qDebug() << "下载信息:::" << res << endl;

        QTextStream stream(&res);
        QString line;

        while (stream.readLineInto(&line))
        {
            QStringList parts = line.split('\\');
            if (parts.size() == 3)
            {
                QString filename = parts[0];
                bool ok;
                int chunksize = parts[1].toInt(&ok);
                if (ok)
                {
                    QMutexLocker locker(&downloadProgressMutex);
                    DownLoadInfo.append({filename, chunksize});
                    downloadProgress[filename] = chunksize + 1;
                }
            }
        }
    }
    else if (obj["flag"] == 6) // 传输信息
    {
        QString transferinfo = obj["transferinfo"].toString();
        qDebug() << "传输信息" << transferinfo << endl;

        QVector<TransferFileInfo> result;
        QTextStream stream(&transferinfo);
        QString line;

        while (stream.readLineInto(&line))
        {
            QStringList parts = line.split('\\');
            if (parts.size() == 4)
            {
                QString filename = parts[0];
                QString type = parts[1];
                int chunkIndex = parts[2].toInt();
                int totalChunks = parts[3].toInt();
                qDebug() << filename << type << chunkIndex << totalChunks << endl;
                result.append({filename, type, chunkIndex, totalChunks});
            }
        }
        ShowTransferInfo(result);
    }
    else if (obj["flag"] == 8) // 下载文件
    {
        QString filepath = obj["desfilepath"].toString();
        QString filename = obj["filename"].toString();
        int chunkIndex = obj["chunkIndex"].toInt();
        int totalChunks = obj["totalChunks"].toInt();
        qDebug() << fromname << filename << chunkIndex << totalChunks << endl;
        QByteArray fileData = QByteArray::fromBase64(obj["data"].toString().toUtf8());

        QFile file(filepath + "/" + filename);
        if (file.exists())
        {
//            qDebug() << "文件已存在" << endl;
        }

        if (chunkIndex == 0)
        {
            file.open(QIODevice::WriteOnly);
        }
        else
        {
            file.open(QIODevice::Append);
        }

        if (file.isOpen())
        {
            file.write(fileData);
            file.close();
            if (chunkIndex == totalChunks - 1)
            {
                QJsonObject obj;
                obj["flag"] = 13;
                obj["fromname"] = fromname;
                obj["filename"] = filename;
                qDebug() << "File received successfully:" << filename;
            }
        }
    }
    else
    {
        QString fileinfo = obj["fileinfo"].toString();
        QString button = obj["button"].toString();
        qDebug() << "文件信息" << fileinfo << endl;

        if (button == "传输")
        {
            QVector<TransferFileInfo> result;
            QTextStream stream(&fileinfo);
            QString line;

            while (stream.readLineInto(&line))
            {
                QStringList parts = line.split('\\');
                if (parts.size() == 5)
                {
                    QString filename = parts[0];
                    QString type = parts[1];
                    int chunkIndex = parts[2].toInt();
                    int totalChunks = parts[3].toInt();
                    result.append({filename, type, chunkIndex, totalChunks});
                }
            }
            ShowTransferInfo(result);
        }
        else
        {
            qDebug() << "button：全部文件" << endl;
            QVector<FileInfo> result;
            QTextStream stream(&fileinfo);
            QString line;

            while (stream.readLineInto(&line))
            {
                QStringList parts = line.split('\\');
                if (parts.size() == 5)
                {
                    QString filename = parts[0];
                    if (obj["flag"] == 7)
                    {
                        QMutexLocker locker(&uploadProgressMutex);
                        uploadProgress.remove(filename);
                    }
                    QString filesize = parts[1];
                    QString filetype = parts[2];
                    QString time = parts[3];
                    result.append({filename, filesize, filetype, time});
                }
            }
            ShowFileInfo(result);
        }
    }
}

// 显示文件信息
void MainFace::ShowFileInfo(QVector<FileInfo> &result)
{
    ui->listWidget->clear();
    for(int i = 0; i < result.size(); i++) // 遍历
    {
        QListWidgetItem * item = new QListWidgetItem; // 创建新的列表项，QListWidgetItem是QListWidget中的基本单元，表示单个条目
        item->setSizeHint(QSize(ui->listWidget->width(),50)); // 设置列表项的高度和宽度
        FileItem *w = new FileItem; // 创建个性化小部件
        w->setFixedSize(item->sizeHint()); // 设置小部件的大小与列表项匹配
        w->SetHead(result[i].fileType);
        w->SetFileName(result[i].fileName); // 设置头像
        w->SetFileSize(result[i].fileSize); // 设置名称
        w->SetFileType(result[i].fileType);
        w->SetTime(result[i].Time);
        ui->listWidget->addItem(item); // 将新创建的列表项添加到ui->listWidget中
        ui->listWidget->setItemWidget(item,w); // 将小部件w设置到由item表示的列表项上，在listWidget中，item所对应的列表项将不再显示默认的文本或图标，而是显示我们自定义的小部件w
    }
}

// 显示传输进度信息
void MainFace::ShowTransferInfo(QVector<TransferFileInfo> &result)
{
    ui->listWidget->clear();
    for(int i = 0; i < result.size(); i++) // 遍历
    {
        QListWidgetItem * item = new QListWidgetItem; // 创建新的列表项，QListWidgetItem是QListWidget中的基本单元，表示单个条目
        item->setSizeHint(QSize(ui->listWidget->width() / 2,50)); // 设置列表项的高度和宽度

        // 创建一个包含 FileItem 和进度条的容器
        QWidget *container = new QWidget;
        QHBoxLayout *layout = new QHBoxLayout(container);
        // 设置布局内部件的对齐方式为垂直居中
        layout->setAlignment(Qt::AlignVCenter);

        TransferInfo *w = new TransferInfo; // 创建个性化小部件
        w->setFixedSize(item->sizeHint()); // 设置小部件的大小与列表项匹配
        w->SetFileName(result[i].fileName); // 设置头像
        w->SetFileType(result[i].Type);
        w->setFixedSize(600, 30);

        // 创建进度条
        QProgressBar *progressBar = new QProgressBar;
        progressBar->setValue(0);
        progressBar->setRange(0, result[i].totalChunks);
        progressBar->setValue(result[i].chunkIndex);
        progressBar->setFixedSize(300, 20);
        progressBar->setAlignment(Qt::AlignHCenter);

        // 将 FileItem 和进度条添加到容器布局中
        layout->addWidget(w);
        layout->addWidget(progressBar);

        // 将容器设置为列表项的小部件
        ui->listWidget->addItem(item);
        ui->listWidget->setItemWidget(item, container);

        // 存储进度条指针
        progressBars[result[i].fileName] = progressBar;
    }
}

void MainFace::GetSocketAndName(QTcpSocket *socket, const QString &fromname)
{
    this->socket = socket;

    this->fromname = fromname;
    ui->label_photo->setScaledContents(true);
    ui->label_photo->setPixmap(UserInfo::getInstance()->GetPhoto(fromname));

    // 向服务器请求上传进度
    QJsonObject upobj;
    upobj["flag"] = 10;
    upobj["fromname"] = fromname;
    QJsonDocument upjsonDoc(upobj);
    QByteArray upjsonData = upjsonDoc.toJson();
    WriteToServer(upobj);

    // 向服务器请求下载进度
    QJsonObject downobj;
    downobj["flag"] = 11;
    downobj["fromname"] = fromname;
    QJsonDocument downjsonDoc(downobj);
    QByteArray downjsonData = downjsonDoc.toJson();
    WriteToServer(downobj);
}

void MainFace::on_pushButton_all_clicked()
{
    ui->listWidget->clear();
    QJsonObject obj; // 构建Json对象
    obj["flag"] = 3; // 请求类型为ALL
    obj["fromname"] = fromname;
    WriteToServer(obj); // 发送到服务器
}

void MainFace::on_pushButton_photo_clicked()
{
    ui->listWidget->clear();
    QJsonObject obj; // 构建Json对象
    obj["flag"] = 4; // 请求类型为LOGIN
    obj["fromname"] = fromname;
    WriteToServer(obj); // 发送到服务器
}

void MainFace::on_pushButton_video_clicked()
{
    ui->listWidget->clear();
    QJsonObject obj; // 构建Json对象
    obj["flag"] = 5; // 请求类型为LOGIN
    obj["fromname"] = fromname;
    WriteToServer(obj); // 发送到服务器
}

void MainFace::on_pushButton_transfer_clicked()
{
    ui->listWidget->clear();
    QJsonObject obj; // 构建Json对象
    obj["flag"] = 6; // 请求类型为TRANSFER
    obj["fromname"] = fromname;
    WriteToServer(obj); // 发送到服务器
}

void MainFace::on_pushButton_upload_clicked()
{
    QStringList filepaths = QFileDialog::getOpenFileNames(this, QStringLiteral("获取文件"), "C:\\Users\\Default\\Desktop");
    if (filepaths.isEmpty())
    {
        return;
    }

    foreach(const QString &filepath, filepaths)
    {
        QFileInfo file(filepath);
        QString filename = file.fileName();
        int startChunk = 0;
        {
            QMutexLocker locker(&uploadProgressMutex);
            if (!uploadProgress.contains(filename)) {
                // 如果 filename 不存在，将其添加到 uploadProgress 中并设置初始值为 0
                uploadProgress.insert(filename, 0);
            }
            startChunk = uploadProgress.value(filename, 0);
        }

        /* 线程处理 */
        MyThread *thread = new MyThread(MyThread::Upload, fromname, filepath, filename, ui->buttonGroup->checkedButton()->text(), startChunk, "192.168.157.128", 8080);
        thread->start();  // 启动线程
        connect(thread, &MyThread::showInfo, this, &MainFace::handleShowInfo);
        connect(thread, &MyThread::showload, this, &MainFace::handleShowTransferInfo);
        connect(thread, &MyThread::progressChanged, [this, filename](int progress){
                   handleUploadProgress(filename, progress);
               });
    }
}

void MainFace::on_pushButton_download_clicked()
{
    if (selectFile.size() == 0)
    {
        return;
    }
    QString filepath = QFileDialog::getExistingDirectory(this, QStringLiteral("选择下载路径"), "C:\\Users\\Default\\Desktop");
    if (filepath.size() == 0)
    {
        return;
    }

    foreach(const QString &filename, selectFile)
    {
        if (!downloadProgress.contains(filename))
        {
            // 如果 filename 不存在，将其添加到 uploadProgress 中并设置初始值为 0
            downloadProgress.insert(filename, 0);
        }
        int startChunk = downloadProgress.value(filename, 0);
        /* 线程处理 */
        MyThread *thread = new MyThread(MyThread::Download, fromname, filepath, filename, ui->buttonGroup->checkedButton()->text(), startChunk, "192.168.157.128", 8080);
        thread->start();  // 启动线程
        connect(thread, &MyThread::showInfo, this, &MainFace::handleShowInfo);
        connect(thread, &MyThread::showload, this, &MainFace::handleShowTransferInfo);
        connect(thread, &MyThread::progressChanged, [this, filename](int progress)
                {
                   handleUploadProgress(filename, progress);
               });
    }
}

void MainFace::on_pushButton_remove_clicked()
{
    QString filename;
    // 模拟获取当前选中的 FileItem 并读取信息
    QListWidgetItem* currentItem = ui->listWidget->currentItem();
    if (currentItem)
    {
        qDebug() << "进入" << endl;
        FileItem* fileItem = qobject_cast<FileItem*>(ui->listWidget->itemWidget(currentItem));
        if (fileItem)
        {
            qDebug() << "文件名: " << fileItem->GetFileName();
            filename = fileItem->GetFileName();
        }
    }
    else
    {
        return;
    }

    QAbstractButton *checkedButton = ui->buttonGroup->checkedButton();
    if (checkedButton)
    {
        qDebug() << "当前选中的按钮文本: " << checkedButton->text();
    }

    QJsonObject obj; // 构建Json对象
    obj["flag"] = 9; // 请求类型为LOGIN
    obj["fromname"] = fromname;
    obj["filename"] = filename;
    obj["button"] = checkedButton->text();
    WriteToServer(obj); // 发送到服务器

    ui->listWidget->clear();
}

void MainFace::handleShowInfo(const QString &filename)
{
    progressBars.remove(filename);
    uploadProgress[filename] = 0;
    QString button = ui->buttonGroup->checkedButton()->text();
    qDebug() << button << endl;

    if (button == "全部文件")
    {
        ui->listWidget->clear();
        QJsonObject obj; // 构建Json对象
        obj["flag"] = 3; // 请求类型为ALL
        obj["fromname"] = fromname;
        WriteToServer(obj); // 发送到服务器
    }
    else if (button == "图片")
    {
        ui->listWidget->clear();
        QJsonObject obj; // 构建Json对象
        obj["flag"] = 4; // 请求类型为ALL
        obj["fromname"] = fromname;
        WriteToServer(obj); // 发送到服务器
    }
    else if (button == "视频")
    {
        ui->listWidget->clear();
        QJsonObject obj; // 构建Json对象
        obj["flag"] = 5; // 请求类型为ALL
        obj["fromname"] = fromname;
        WriteToServer(obj); // 发送到服务器
    }
    else if (button == "传输")
    {
        ui->listWidget->clear();
        QJsonObject obj; // 构建Json对象
        obj["flag"] = 6; // 请求类型为ALL
        obj["fromname"] = fromname;
        WriteToServer(obj); // 发送到服务器
    }
}

void MainFace::handleShowTransferInfo()
{
    if (ui->buttonGroup->checkedButton()->text() == "传输")
    {
        ui->listWidget->clear();
        QJsonObject obj; // 构建Json对象
        obj["flag"] = 6; // 请求类型为ALL
        obj["fromname"] = fromname;
        WriteToServer(obj); // 发送到服务器
    }
}

void MainFace::handleUploadProgress(const QString &filename, int progress)
{
    if (progressBars.contains(filename))
    {
        progressBars[filename]->setValue(progress);
    }
}

void MainFace::on_listWidget_itemClicked(QListWidgetItem *item)
{
    QString button = ui->buttonGroup->checkedButton()->text();
    if (button == "传输")
    {
        return;
    }
    QWidget *itemWidget = ui->listWidget->itemWidget(item);
    FileItem *fileItem = qobject_cast<FileItem*>(itemWidget);

    QString filename = fileItem->GetFileName();

    if (selectFile.contains(filename))
    {
        selectFile.removeOne(filename);
        fileItem->SetSelect();
    }
    else
    {
        selectFile.append(filename);
        fileItem->SetSelect();
    }
    qDebug() << selectFile << endl;
}
